package com.itheima.mp.gateway.util;

import io.jsonwebtoken.*;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class JwtUtil {

    // TOKEN的有效期（3600秒 = 1小时）
    private static final long TOKEN_TIME_OUT = 3600 * 1000;  // 毫秒
    // 加密密钥（建议64位以上字符）
    private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjYxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTA=";
    // 最小刷新间隔（300秒 = 5分钟）
    private static final long REFRESH_TIME = 300 * 1000;  // 毫秒

    /**
     * 生成Token
     */
    public static String getToken(Long id) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", id);

        long currentTime = System.currentTimeMillis();
        return Jwts.builder()
                .setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date(currentTime))
                .setSubject("system")
                .setIssuer("itheima")
                .setAudience("user")
                .compressWith(CompressionCodecs.GZIP)
                // 低版本JJWT：先指定算法，再指定密钥（与高版本相反）
                .signWith(SignatureAlgorithm.HS512, generalKey())  // 修正参数顺序
                .setExpiration(new Date(currentTime + TOKEN_TIME_OUT))
                .addClaims(claims)
                .compact();
    }

    /**
     * 解析Token
     */
    private static Jws<Claims> parseToken(String token) throws JwtException {
        return Jwts.parser()
                .setSigningKey(generalKey())  // 验证密钥
                .parseClaimsJws(token);
    }

    /**
     * 获取Token中的自定义数据
     */
    public static Claims getClaims(String token) {
        try {
            return parseToken(token).getBody();
        } catch (ExpiredJwtException e) {
            return e.getClaims();
        } catch (JwtException e) {
            return null;
        }
    }

    /**
     * 验证Token状态
     */
    public static int verifyToken(Claims claims) {
        if (claims == null) {
            return 2;  // 无效
        }
        Date expiration = claims.getExpiration();
        long now = System.currentTimeMillis();
        if (expiration == null) {
            return 2;
        }
        if (expiration.after(new Date(now + REFRESH_TIME))) {
            return -1;  // 有效无需刷新
        } else if (expiration.after(new Date(now))) {
            return 0;   // 可刷新
        } else {
            return 1;   // 已过期
        }
    }

    /**
     * 生成密钥（适配低版本）
     */
    private static byte[] generalKey() {  // 低版本直接返回字节数组
        return TOKEN_ENCRY_KEY.getBytes(StandardCharsets.UTF_8);
    }

    public static void main(String[] args) {
        String token = getToken(21L);
        System.out.println("生成的Token：" + token);

        Claims claims = getClaims(token);
        if (claims != null) {
            System.out.println("解析的用户ID：" + claims.get("id"));
            System.out.println("Token状态：" + getStatusDesc(verifyToken(claims)));
        } else {
            System.out.println("Token解析失败");
        }
    }

    private static String getStatusDesc(int status) {
        switch (status) {
            case -1: return "有效且无需刷新";
            case 0: return "可刷新";
            case 1: return "已过期";
            case 2: return "无效";
            default: return "未知状态";
        }
    }
}